package com.wangbo.hc;

import com.sun.jna.Pointer;
import lombok.Data;
import lombok.SneakyThrows;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;

@Data
public class MyFMSGCallBack implements HCNetSDK.FMSGCallBack_V31 {
    public LinkedList<SnapDTO> queue ;
    public AtomicInteger picId = new AtomicInteger(1000000);

    public MyFMSGCallBack(LinkedList queue) {
        this.queue = queue;
    }

    @Override
    public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        AlarmDataHandle(lCommand, pAlarmer, pAlarmInfo);
        return true;
    }

    @SneakyThrows
    private void AlarmDataHandle(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo) {
        System.out.println(String.format("lCommand=0x%x", lCommand));
        // 实时人脸抓拍上传
        if (lCommand == HCNetSDK.COMM_UPLOAD_FACESNAP_RESULT) {
            SnapDTO snapDTO = new SnapDTO();

            // 摄像头信息
            snapDTO.setCameraIp(new String(pAlarmer.sDeviceIP).trim());
            snapDTO.setServerPort(pAlarmer.wLinkPort);

            // 结构化数据
            HCNetSDK.NET_VCA_FACESNAP_RESULT faceSnapResult = new HCNetSDK.NET_VCA_FACESNAP_RESULT();
            faceSnapResult.write();
            Pointer pFaceSnapInfo = faceSnapResult.getPointer();
            pFaceSnapInfo.write(0, pAlarmInfo.getByteArray(0, faceSnapResult.size()), 0, faceSnapResult.size());
            faceSnapResult.read();

            // 人脸PicID 人脸评分
            snapDTO.setPicId(faceSnapResult.dwFacePicID);
            snapDTO.setFaceScore(faceSnapResult.dwFaceScore);
            // 人脸图
            if (faceSnapResult.dwFacePicLen > 0) {
                byte[] smallImageBytes = faceSnapResult.pBuffer1.getByteArray(0, faceSnapResult.dwFacePicLen);
                snapDTO.setSmallImageBytes(smallImageBytes);
            }
            // 背景图
            if (faceSnapResult.dwBackgroundPicLen > 0) {
                byte[] bigImageBytes = faceSnapResult.pBuffer2.getByteArray(0, faceSnapResult.dwBackgroundPicLen);
                snapDTO.setBigImageBytes(bigImageBytes);
            }
            // 人脸特征
            HCNetSDK.NET_VCA_HUMAN_FEATURE faceFeature = faceSnapResult.struFeature;
            snapDTO.setAge((int) faceFeature.byAge); // 年龄: 0-表示“未知”（算法不支持）,0xff-算法支持，但是没有识别出来
            snapDTO.setGender((int) faceFeature.bySex); // 性别, 0-表示“未知”（算法不支持）,1 – 男 , 2 – 女, 0xff-算法支持，但是没有识别出来
            snapDTO.setMask((int) faceFeature.byMask); // 是否戴口罩 0-表示“未知”（算法不支持）,1 – 不戴, 2 – 戴, 0xff-算法支持，但是没有识别出来
            snapDTO.setEyeClass((int) faceFeature.byEyeGlass); // 是否戴眼镜 0-表示“未知”（算法不支持）,1 – 不戴, 2 – 戴,0xff-算法支持，但是没有识别出来
            // 温度数据
            if (faceSnapResult.byAddInfo == 1) {
                HCNetSDK.NET_VCA_FACESNAP_ADDINFO strAddInfo = new HCNetSDK.NET_VCA_FACESNAP_ADDINFO();
                strAddInfo.write();
                Pointer pAddInfo = strAddInfo.getPointer();
                pAddInfo.write(0, faceSnapResult.pAddInfoBuffer.getByteArray(0, strAddInfo.size()), 0, strAddInfo.size());
                strAddInfo.read();

                snapDTO.setFaceSnapThermometryEnabled((int) strAddInfo.byFaceSnapThermometryEnabled); //人脸抓拍测温使能 1-开启 0-关闭
                snapDTO.setAlarmTemperature(strAddInfo.fAlarmTemperature); // 测温报警警阈值（精确到小数点后1位）
                snapDTO.setFaceTemperature(strAddInfo.fFaceTemperature); // 人脸温度（ - 20.0℃~150.0℃，精确到小数点后1位）
                snapDTO.setIsAbnomalTemperature((int) strAddInfo.byIsAbnomalTemperature); // 人脸抓拍测温是否温度异常 1-是 0-否
            }
            // 发送数据给faceLogsService
            queue.add(snapDTO);
        }

        if (lCommand == HCNetSDK.COMM_ITS_PLATE_RESULT) {
            // 结构化数据
            HCNetSDK.NET_ITS_PLATE_RESULT carSnapResult = new HCNetSDK.NET_ITS_PLATE_RESULT();
            carSnapResult.write();
            Pointer pItsPlateInfo = carSnapResult.getPointer();
            pItsPlateInfo.write(0, pAlarmInfo.getByteArray(0, carSnapResult.size()), 0, carSnapResult.size());
            carSnapResult.read();

            // 背景图
            byte[] bigImageBytes = null;
            for (int i = 0; i < carSnapResult.dwPicNum; i++) {
                if (carSnapResult.struPicInfo[i].byType == 1) {
                    bigImageBytes = new byte[carSnapResult.struPicInfo[i].dwDataLen];

                    long offset = 0;
                    ByteBuffer buffers = carSnapResult.struPicInfo[i].pBuffer.getByteBuffer(offset, carSnapResult.struPicInfo[i].dwDataLen);
                    buffers.rewind();
                    buffers.get(bigImageBytes);

                    System.out.println("HC 抓拍图片类型：" + carSnapResult.struPicInfo[i].byType);
                }
            }

            // 人脸图
            for (int i = 0; i < carSnapResult.dwPicNum; i++) {
                if (carSnapResult.struPicInfo[i].byType == 6 || carSnapResult.struPicInfo[i].byType == 7) {
                    SnapDTO snapDTO = new SnapDTO();

                    // 摄像头信息
                    snapDTO.setCameraIp(new String(pAlarmer.sDeviceIP).trim());
                    snapDTO.setServerPort(pAlarmer.wLinkPort);

                    // 车牌
                    String licence = null;
                    licence = new String(carSnapResult.struPlateInfo.sLicense, "GBK").trim();
                    snapDTO.setLicence(licence);

                    // 人脸PicID
                    snapDTO.setPicId(picId.incrementAndGet());

                    byte[] bytes = new byte[carSnapResult.struPicInfo[i].dwDataLen];

                    long offset = 0;
                    ByteBuffer buffers = carSnapResult.struPicInfo[i].pBuffer.getByteBuffer(offset, carSnapResult.struPicInfo[i].dwDataLen);
                    buffers.rewind();
                    buffers.get(bytes);

                    System.out.println("HC 抓拍图片类型：" + carSnapResult.struPicInfo[i].byType);

                    // 抓拍图
                    snapDTO.setSmallImageBytes(bytes);
                    snapDTO.setBigImageBytes(bigImageBytes);

                    // 发送数据给faceLogsService
                    queue.add(snapDTO);
                }
            }
        }
    }
}
